package xx.iverson.listening_manager.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import xx.iverson.listening_manager.entity.AudioFile;
import xx.iverson.listening_manager.result.ReturnResult;
import xx.iverson.listening_manager.service.AudioFileService;

import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.io.File;
import java.util.List;
import java.util.Map;

/**
 * xx.iverson.listening_manager.controller.AudioFileController
 * 描述：
 * on 2025/10/17-上午9:05
 *
 * @author weijx
 */

@RestController
@RequestMapping("/api/audio")
public class AudioFileController {

    @Value("${file.upload-dir:uploads}")
    private String uploadDir;

    @javax.annotation.Resource
    private AudioFileService audioFileService;

    // 获取所有听力文件列表
    @PostMapping("/list")
    public ReturnResult<List<AudioFile>> getAudioList() {
        return audioFileService.getAllAudioFiles();
    }


    @PostMapping("/listByCategory")
    public ReturnResult<List<AudioFile>> getAudioByCategory(@RequestBody Map<String, Integer> request) {
        Integer level1CategoryId = request.get("level1CategoryId");
        Integer level2CategoryId = request.get("level2CategoryId");

        if (level1CategoryId != null) {
            // 如果请求中包含 level1CategoryId，则按一级分类查询
            return audioFileService.getAudioByLevel1CategoryId(level1CategoryId);
        } else if (level2CategoryId != null) {
            // 如果请求中包含 level2CategoryId，则按二级分类查询
            return audioFileService.getAudioByLevel2CategoryId(level2CategoryId);
        } else {
            // 如果两个ID都未提供，返回错误
            return ReturnResult.error(400, "必须提供 level1CategoryId 或 level2CategoryId");
        }
    }

    // 搜索听力文件
    @PostMapping("/search")
    public ReturnResult<List<AudioFile>> searchAudio(@RequestBody Map<String, String> request) {
        try {
            String keyword = request.get("keyword");
            if (keyword == null || keyword.trim().isEmpty()) {
                return ReturnResult.error(400, "搜索关键词不能为空");
            }

            // 调用Service层进行搜索
            List<AudioFile> result = audioFileService.searchAudio(keyword.trim());
            return ReturnResult.success(result);
        } catch (Exception e) {
            return ReturnResult.error(500, "搜索失败: " + e.getMessage());
        }
    }

    // 上传听力文件
    @PostMapping("/upload")
    public ReturnResult<AudioFile> uploadAudio(
            @RequestParam("file") MultipartFile file,
            @RequestParam("title") String title,
            @RequestParam(value = "description", required = false) String description,
            @RequestParam("categoryId") Integer categoryId,
            @RequestParam(value = "isVisible", defaultValue = "true") Boolean isVisible) {

        AudioFile audioFile = new AudioFile();
        audioFile.setTitle(title);
        audioFile.setDescription(description);
        audioFile.setCategoryId(categoryId);
        audioFile.setIsVisible(isVisible);

        return audioFileService.uploadAudio(file, audioFile);
    }

    // 更新听力文件信息
    @PostMapping("/update")
    public ReturnResult<Boolean> updateAudio(@RequestBody AudioFile audioFile) {
        return audioFileService.updateAudioInfo(audioFile);
    }

    // 删除听力文件
    @PostMapping("/delete")
    public ReturnResult<Boolean> deleteAudio(@RequestBody Map<String, Integer> request) {
        Integer audioId = request.get("audioId");
        if (audioId == null) {
            return ReturnResult.error(400, "文件ID不能为空");
        }
        return audioFileService.deleteAudio(audioId);
    }

    // 播放听力文件
    @PostMapping("/play")
    public ReturnResult<String> playAudio(@RequestBody Map<String, Integer> request) {
        Integer audioId = request.get("audioId");
        if (audioId == null) {
            return ReturnResult.error(400, "文件ID不能为空");
        }
        return audioFileService.playAudio(audioId);
    }

    // 下载听力文件
    @PostMapping("/download")
    public ReturnResult<String> downloadAudio(@RequestBody Map<String, Integer> request) {
        Integer audioId = request.get("audioId");
        if (audioId == null) {
            return ReturnResult.error(400, "文件ID不能为空");
        }
        return audioFileService.downloadAudio(audioId);
    }


    @GetMapping("/file/{year}/{month}/{day}/{filename:.+}")
    public ResponseEntity<Resource> getAudioFile(@PathVariable String year,
                                                 @PathVariable String month,
                                                 @PathVariable String day,
                                                 @PathVariable String filename) {

        // 构建文件路径
        String fileSystemPath = year + File.separator + month + File.separator + day + File.separator + filename;
        File file = new File(uploadDir + File.separator + fileSystemPath);

        if (!file.exists() || !file.isFile()) {
            return ResponseEntity.notFound().build();
        }

        // 使用Spring内置的FileSystemResource
        Resource resource = new FileSystemResource(file);

        // 自动识别媒体类型 (audio/mpeg 等)
        MediaType mediaType = MediaTypeFactory.getMediaType(resource)
                .orElse(MediaType.APPLICATION_OCTET_STREAM);

        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        // 允许跨域（如果您决定在Nginx层加，这里可以去掉。现在加上双保险）
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        // 禁止缓存，确保每次都请求最新状态，避免某些浏览器缓存bug
        headers.add(HttpHeaders.CACHE_CONTROL, "no-cache");

        // 返回ResponseEntity，Spring会自动处理Range请求
        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(file.length())
                .contentType(mediaType)
                .body(resource);
    }
}
